package com.tuijian.service.rearrange;

import com.tuijian.util.HbaseUtils;
import com.tuijian.util.RedisUtils;
import com.tuijian.vo.IdScore;
import com.tuijian.vo.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;


@Service
public class ProductRearRange {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private HbaseUtils hbaseUtils;
    /**
     * 商品重排方法
     * @param old_sort 精排排序list
     * @param lambda 多样性参数0~1
     * @return 重排排序list
     */
    public void rearRange(List<Product> old_sort, double lambda){
        List<IdScore> cisList = new ArrayList<>();
        for(int i = 0; i < old_sort.size(); i++){
            Product pro = old_sort.get(i);
            //userid,productid,score有就行，其他没有就没有吧
            cisList.add(new IdScore(pro.getUserId() ,pro.getProductId(), pro.getScore(), 0, ""));
        }
        List<IdScore> new_cisList = iterator(cisList, cisList.size(), lambda);

        //写入redis
        //连接位置需要修改的host和port
        //Jedis jedis = new Jedis("localhost", 6379);
        //String response = jedis.ping();
        //System.out.println(response); // PONG
        //StringBuffer str = new StringBuffer();
        //str.append("{");
//        RedisUtils redisUtils = new RedisUtils();
        List list = new ArrayList<>();
        for (int i = 0; i < new_cisList.size(); i++){
           // str.append(new_cisList.get(i).getProductId() + ":0" + new DecimalFormat("#.00").format(new_cisList.get(i).getRearRangeScore()));
            //if(i<new_cisList.size() - 1) str.append(",");
            list.add(new_cisList.get(i).getProductId());
        }
        System.out.println(new_cisList.get(0));
        System.out.println(new_cisList.get(0).getUserId());

        redisUtils.setCacheNewList("prod" + new_cisList.get(0).getUserId(), list);
        //str.append("}");
//        jedis.set("prod" + new_cisList.get(0).getUserId(),str.toString());
        // 获取存储的数据并输出
        //System.out.println("redis 存储的字符串为: "+ jedis.get(new_cisList.get(0).getUserId()));

        //写入hbase
        try {
            //连接位置
            hbaseUtils.connect("hadoop1,hadoop2,hadoop3","2181");
            Map map=new HashMap();
            //列名统一为info
            map.put("info", org.apache.commons.lang.StringUtils.join(list.toArray(), ','));
            //表名rearrange，rowkey为用户id，列族名为range，map为信息
            hbaseUtils.put("rearrange",old_sort.get(0).getUserId(),"range",map);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                hbaseUtils.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * mmr迭代
     * @param R 商品排序的list
     * @param topNum list的size
     * @param lambda 多样性参数
     * @return
     */
    public List<IdScore> iterator(List<IdScore> R, int topNum, double lambda) {
        AtomicInteger counter = new AtomicInteger(0);
        List<IdScore> S = new ArrayList(topNum);
        while (S.size() < topNum && R.size() > 0) {
            double maxMMR = 0d;
            IdScore maxIdScore = R.get(0);
            // 进行迭代
            for (int i = 0; i < R.size(); i++) {
                IdScore di = R.get(i);
                double maxSim2 = 0d;
                for (int j = 0; j < S.size(); j++) {
                    counter.getAndIncrement();
                    IdScore dj = S.get(j);
                    double sim2Score = similar(di.getScore(), dj.getScore());
                    if (j == 0) {
                        maxSim2 = sim2Score;
                    }
                    if (sim2Score > maxSim2) {
                        maxSim2 = sim2Score;
                    }
                }
                // 计算MMR
                double mmr = lambda * di.getScore() - (1 - lambda) * maxSim2;
                if (i == 0) {
                    maxMMR = mmr;
                }
                if (mmr > maxMMR) {
                    maxMMR = mmr;
                    maxIdScore = di;
                }
            }
            maxIdScore.setRearRangeScore(maxMMR);
            R.remove(maxIdScore);
            S.add(maxIdScore);
        }
        return S;
    }

    /**
     * 商品相似度(java商品没有多级分类，废弃)
     * @param di i商品分类号
     * @param dj j商品分类号
     * @return 相似度
     */
    public double similar_ (String di, String dj){
        //分解类别编号
        int[] di_arr = {Integer.parseInt(di.split("-")[0]),Integer.parseInt(di.split("-")[1]),Integer.parseInt(di.split("-")[2])};
        int[] dj_arr = {Integer.parseInt(dj.split("-")[0]),Integer.parseInt(dj.split("-")[1]),Integer.parseInt(dj.split("-")[2])};

        //具体级差分数待定，暂定为0.2
        if(di_arr[0] == dj_arr[0]) return 0.8;
        if(di_arr[0] != dj_arr[0]){
            if(di_arr[1] == dj_arr[1]) return 0.6;
            if(di_arr[1] != dj_arr[1]) {
                if(di_arr[1] == dj_arr[1]) return 0.4;
                if(di_arr[1] != dj_arr[1]) return 0.2;
            }
        }
        return 0.2;
    }

    /**
     * 商品相似度（根据得分散列赋分 + 随机抽样 + 正态分布）
     * @param di_score
     * @param dj_score
     * @return
     */
    public double similar (double di_score, double dj_score){
        //定义0.8为高位，0.5为中位，0.3为低位
        if(di_score >= 0.8 && dj_score >= 0.8){
            if(new Random().nextInt() >= 0.8) return 0.6;
            return 0.8;
        }else {
            if((0.8 > di_score && di_score >= 0.5) && (0.8 > dj_score && dj_score >= 0.5)){
                double la = Double.parseDouble(new DecimalFormat("0.00").format(new Random().nextDouble()));
                return 0.2 + la*0.5 + Math.abs(new Random().nextGaussian())/20;
            }else {
                double la = Double.parseDouble(new DecimalFormat("0.00").format(new Random().nextDouble()));
                return la*0.3 + Math.abs(new Random().nextGaussian())/10;
            }
        }
    }
}
